package com.pm.buglist.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pm.buglist.domain.*;
import com.pm.buglist.mapper.*;
import com.pm.buglist.service.WavieOrderService;
import com.pm.common.config.ParamConfig;
import com.pm.common.core.domain.AjaxResult;
import com.pm.common.core.domain.entity.SysUser;
import com.pm.common.core.redis.RedisCache;
import com.pm.common.enums.BugsStatus;
import com.pm.common.utils.SecurityUtils;
import com.pm.common.utils.WeChatNoteUtils;
import com.pm.system.mapper.SysUserMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 * waive单申请记录表 服务实现类
 * </p>
 *
 * @author wwm
 * @since 2024-06-19
 */
@Service
public class WavieOrderServiceImpl extends ServiceImpl<WavieOrderMapper, WavieOrder> implements WavieOrderService {
    @Resource
    private BugsMapper bugsMapper;

    @Resource
    private BugDescriptionMapper descriptionMapper;

    @Resource
    private BugsHandleLogMapper handleLogMapper;

    @Resource
    private BugsRdHandleMapper rdHandleMapper;

    @Resource
    private WeChatNoteUtils weChatNoteUtils;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private ParamConfig paramConfig;

    @Resource
    private RedisLockRegistry redisLockRegistry;//分布式锁

    @Resource
    private RedisCache redisCache;

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult approverWaive(WavieOrder wavieOrder) {
        try {
            //获取登录人id
            Long userId = SecurityUtils.getUserId();
            //姓名
            String username = SecurityUtils.getUsername();
            //修改bug状态
            Long bId = wavieOrder.getBId();
            if(ObjectUtils.isEmpty(bId)){
                return AjaxResult.error("操作的bug不能为空");
            }
            //验证当前登录人是否是当前bug责任人
            //查询最新的研发处理人
            List<BugsRdHandle> rdHandles = rdHandleMapper.findBugsRdHandleByBid(bId);
            if(!CollectionUtils.isEmpty(rdHandles)) {
                Boolean flage = false;
                for (BugsRdHandle rdHandle : rdHandles) {
                    if (rdHandle.getUserId().equals(userId)) {
                        flage = true;
                        break;
                    }
                }
                if (!flage) {
                    return AjaxResult.error("你不是当前bug责任人,无权执行此操作");
                }
            }

            //加锁
            String key="approve:"+bId;
            Lock reentrantLock = redisLockRegistry.obtain(key);
            try {
                reentrantLock.lock();
                String cacheObject = redisCache.getCacheObject(key);
                if(!StringUtils.isEmpty(cacheObject)){
                    return AjaxResult.error("当前bug已经申请waive操作，请勿重复操作！");
                }
                //执行操作
                Bugs bugs = new Bugs();
                bugs.setId(bId);
                bugs.setBugStatus(BugsStatus.APPROVER_WAIVE.getStatus());//设置申请废弃
                bugs.setUpdateTime(LocalDateTime.now());
                bugs.setUpdateUser(userId);
                bugsMapper.updateById(bugs);
                //插入waive单记录
                wavieOrder.setCreateTime(LocalDateTime.now());
                wavieOrder.setCreateUser(userId);
                baseMapper.insert(wavieOrder);

                //查找最新的描述
                BugDescription description = descriptionMapper.findBugDescriptionByBid(bId);
                //记录bug处理日志
                BugsHandleLog bugsHandleLog = new BugsHandleLog();
                bugsHandleLog.setBugId(bugs.getId());
                bugsHandleLog.setBugStatus(bugs.getBugStatus());
                bugsHandleLog.setBugTitle(bugs.getBugTitle());
                if(!ObjectUtils.isEmpty(description)){
                    bugsHandleLog.setVersion(description.getVersion());//最新的版本
                }
                bugsHandleLog.setHandleUser(userId);
                bugsHandleLog.setCreateTime(LocalDateTime.now());
                handleLogMapper.insert(bugsHandleLog);
                //记录操作标识
                redisCache.setCacheObject(key,"ok",24, TimeUnit.HOURS);
            } finally {
                //解锁
                reentrantLock.unlock();
            }

            //发送废弃消息通知对应的DQE
            new Thread(()->{
                //根据Bug id 查询对应的bug
                Bugs byId = bugsMapper.selectById(bId);
                Long createUser = byId.getCreateUser();
                SysUser user = sysUserMapper.selectUserById(createUser);
                if(!ObjectUtils.isEmpty(user)){
                    String jobNumber = user.getJobNumber();
                    ArrayList<String> jobNums = new ArrayList<>();
                    jobNums.add(jobNumber);
                    List<String> context=new ArrayList<>();
                    String msg="你好,"+user.getUserName()+","+username+"向你提报了一个bug废弃申请，可在“bug管理=》Waive申请”菜单栏目下执行废弃操作。";
                    String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                    context.add(msg);
                    context.add(msg1);
                    weChatNoteUtils.sendWeChatNoteByJobNumber(jobNums,context);
                }
            }).start();

            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("申请废弃异常:"+ JSONObject.toJSONString(e));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("申请废弃异常");
        }
    }

    @Override
    public List<JSONObject> findProjectListByWaiveOrder() {
        return baseMapper.getProjectListByWaiveOrder();
    }

}
